package com.regex.web.config;

import java.util.HashMap;
import java.util.Map;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.regex.web.security.OAuth2ShiroRealm;

/**
 * Shiro 权限控制集成
 */
@Configuration
public class ShiroConfig {

	private static Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

	public ShiroConfig() {
		logger.info("ShiroConfig Init...");
	}

	/**
	 * 将自己的验证方式加入容器
	 */
	@Bean
	public OAuth2ShiroRealm myShiroRealm() {
		OAuth2ShiroRealm OAuth2ShiroRealm = new OAuth2ShiroRealm();
		// 启用缓存,默认false
		OAuth2ShiroRealm.setCachingEnabled(true);
		// 启用身份验证缓存，即缓存AuthenticationInfo信息，默认false；
		OAuth2ShiroRealm.setAuthenticationCachingEnabled(false);
		// 缓存AuthenticationInfo信息的缓存名称,即配置在ehcache.xml中的cache name
		OAuth2ShiroRealm.setAuthenticationCacheName("authenticationCache");
		// 启用授权缓存，即缓存AuthorizationInfo信息，默认false；
		OAuth2ShiroRealm.setAuthorizationCachingEnabled(true);
		// 缓存AuthorizationInfo信息的缓存名称；
		OAuth2ShiroRealm.setAuthorizationCacheName("authorizationCache");

		return OAuth2ShiroRealm;
	}

	/**
	 * 权限管理，配置主要是Realm的管理认证
	 */
	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(myShiroRealm());
		// 注入EhCacheManager缓存管理器
		securityManager.setCacheManager(ehCacheManager());
		securityManager.setSessionManager(mySessionManager());
		return securityManager;
	}

	@Bean
	public EnterpriseCacheSessionDAO mySessionDao() {
		System.out.println("ShiroConfiguration.mySessionDao()");
		EnterpriseCacheSessionDAO mySessionDao = new EnterpriseCacheSessionDAO();
		mySessionDao.setActiveSessionsCacheName("shiro-activeSessionCache");
//      mySessionDao.setSessionIdGenerator(sessionIdGenerator());
		return mySessionDao;
	}

//    @Bean
//    public Collection<SessionListener> sessionListeners() {
//      Collection<SessionListener> listeners = new ArrayList<>();
//      listeners.add(myShiroSessionListener());
//      return listeners;
//    }
//    
//    @Bean
//    public MyShiroSessionListener myShiroSessionListener() {
//      return new MyShiroSessionListener();
//  }

	/**
	 * 加入注解的使用，不加入这个注解不生效
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
		return authorizationAttributeSourceAdvisor;
	}

	@Bean
	public ExecutorServiceSessionValidationScheduler sessionValidationScheduler() {
		ExecutorServiceSessionValidationScheduler sessionValidationScheduler = new ExecutorServiceSessionValidationScheduler();
		sessionValidationScheduler.setInterval(3600000);
		return sessionValidationScheduler;
	}

	/**
	 * 配置自定义的密码比较器
	 */
//    @Bean(name = "credentialsMatcher")
//    public CredentialsMatcher credentialsMatcher() {
//        return new CredentialsMatcher();
//    }

	@Bean(name = "ehcacheManager")
	public EhCacheManager ehCacheManager() {
		logger.info("注入Shiro的缓存管理器-->ehCacheManager", EhCacheManager.class);
		EhCacheManager cacheManager = new EhCacheManager();
		cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
		return cacheManager;
	}

	/**
	 * Filter工厂，设置对应的过滤条件和跳转条件
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		Map<String, String> map = new HashMap<>();
		// 对所有用户认证
		map.put("/sys/**", "authc");
		map.put("/main", "authc");
		map.put("/index", "authc");
		map.put("/", "authc");
		// 不拦截URL
		map.put("/tologin", "anon");
		map.put("/static/**", "anon");
		map.put("/api/**", "anon");
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		shiroFilterFactoryBean.setLoginUrl("/login");
		shiroFilterFactoryBean.setUnauthorizedUrl("/error");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
		return shiroFilterFactoryBean;
	}

	@Bean(name = "lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		logger.info("ShiroConfiguration--lifecycleBeanPostProcessor");
		return new LifecycleBeanPostProcessor();
	}

	@Bean
	public DefaultWebSessionManager mySessionManager() {
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		// 将sessionIdUrlRewritingEnabled属性设置成false
		sessionManager.setSessionIdUrlRewritingEnabled(false);

		sessionManager.getSessionIdCookie().setName("sId");
		sessionManager.setGlobalSessionTimeout(3600000);
		sessionManager.setDeleteInvalidSessions(true);
		sessionManager.setSessionValidationScheduler(sessionValidationScheduler());
		sessionManager.setSessionValidationSchedulerEnabled(true);
		sessionManager.setSessionDAO(mySessionDao());
		return sessionManager;
	}
}
